home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1997 #1
/
Amiga Plus CD - 1997 - No. 01.iso
/
pd
/
programmierung
/
oberonv4
/
demos
/
swarm.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1990-01-01
|
6KB
|
152 lines
Syntax10.Scn.Fnt
MODULE Swarm; (* MB 25.1.90 *)
IMPORT
Oberon, Display, Viewers, Input, Texts, Display1;
CONST
Border = 50;
BeeVel = 11;
WaspVel = 12;
MaxWasps = 10;
MaxBees = 500;
TYPE
Point = RECORD
x, y: INTEGER
END;
Insect = RECORD
pos: ARRAY 3 OF Point;
vx, vy: INTEGER
END;
VAR
Wasps: ARRAY MaxWasps OF Insect;
Bees: ARRAY MaxBees OF Insect;
seed: LONGINT;
NrWasps, NrBees, Delay, WaspAcc, BeeAcc: INTEGER;
firstTime: BOOLEAN;
F: Display.Frame;
PROCEDURE random(): INTEGER;
BEGIN seed := (seed + 773)*13 MOD 99991; RETURN SHORT(seed MOD 32749)
END random;
PROCEDURE Rand(x: INTEGER): INTEGER;
BEGIN RETURN random() MOD x - x DIV 2
END Rand;
PROCEDURE Wait(d: LONGINT);
VAR t, t1: LONGINT;
BEGIN
t := Oberon.Time();
REPEAT t1 := Oberon.Time() UNTIL t+d <= t1
END Wait;
PROCEDURE InitWasp(VAR Wasp: Insect);
BEGIN
Wasp.pos[0].x := Border + random() MOD (Display.Width-2*Border);
Wasp.pos[0].y := Border + random() MOD (Display.Height-2*Border);
Wasp.pos[1] := Wasp.pos[0];
Wasp.vx := 0; Wasp.vy := 0
END InitWasp;
PROCEDURE InitBee(VAR Bee: Insect);
VAR j: INTEGER;
BEGIN
j := random() MOD Display.Width; Bee.pos[0].x := j; Bee.pos[1].x := j;
j := random() MOD Display.Height; Bee.pos[0].y := j; Bee.pos[1].y := j;
Bee.vx := Rand(7); Bee.vy := Rand(7)
END InitBee;
PROCEDURE InitSwarm;
VAR i: INTEGER;
BEGIN
seed := Oberon.Time() MOD 231; (*DIM(Wasps, NrWasps); DIM(Bees, NrBees);*)
NEW(F); F.X := 0; F.Y := 0; F.W := Display.Width; F.H := Display.Height; firstTime := TRUE;
i := 0; WHILE i < NrWasps DO InitWasp(Wasps[i]); INC(i) END;
i := 0; WHILE i < NrBees DO InitBee(Bees[i]); INC(i) END
END InitSwarm;
PROCEDURE Age(VAR i: Insect);
BEGIN i.pos[2] := i.pos[1]; i.pos[1] := i.pos[0]
END Age;
PROCEDURE BoundSpeed(VAR i: Insect; limit: INTEGER);
BEGIN
IF i.vx > limit THEN i.vx := limit ELSIF i.vx < -limit THEN i.vx := -limit END;
IF i.vy > limit THEN i.vy := limit ELSIF i.vy < -limit THEN i.vy := -limit END
END BoundSpeed;
PROCEDURE AccelerateWasp(VAR Wasp: Insect);
BEGIN
Wasp.vx := Wasp.vx+Rand(WaspAcc); Wasp.vy := Wasp.vy+Rand(WaspAcc);
BoundSpeed(Wasp, WaspVel)
END AccelerateWasp;
PROCEDURE ReflectWasp(VAR Wasp: Insect);
BEGIN
IF (Wasp.pos[0].x < Border) OR (Wasp.pos[0].x > Display.Width-Border-1) THEN
Wasp.vx := -Wasp.vx; INC(Wasp.pos[0].x, Wasp.vx)
END;
IF (Wasp.pos[0].y < Border) OR (Wasp.pos[0].y > Display.Height-Border-1) THEN
Wasp.vy := -Wasp.vy; INC(Wasp.pos[0].y, Wasp.vy)
END
END ReflectWasp;
PROCEDURE AccelerateBee(VAR Bee: Insect);
VAR dx, dy, distance, dx1, dy1, distance1, i: INTEGER;
BEGIN
i := 0; distance := 10000;
WHILE i < NrWasps DO
dx1 := Wasps[i].pos[1].x-Bee.pos[1].x; dy1 := Wasps[i].pos[1].y-Bee.pos[1].y; distance1 := ABS(dx1)+ABS(dy1);
IF distance1 < distance THEN dx := dx1; dy := dy1; distance := distance1 END;
INC(i)
END;
IF distance = 0 THEN distance := 1 END;
Bee.vx := Bee.vx + (dx*BeeAcc) DIV distance; Bee.vy := Bee.vy + (dy*BeeAcc) DIV distance;
BoundSpeed(Bee, BeeVel)
END AccelerateBee;
PROCEDURE Move(VAR i: Insect);
BEGIN i.pos[0].x := i.pos[1].x + i.vx; i.pos[0].y := i.pos[1].y + i.vy
END Move;
PROCEDURE Draw(VAR i: Insect);
BEGIN
IF ~firstTime THEN Display1.Line(F, Display.white, i.pos[1].x, i.pos[1].y, i.pos[2].x, i.pos[2].y, Display.invert) END;
Display1.Line(F, Display.white, i.pos[0].x, i.pos[0].y, i.pos[1].x, i.pos[1].y, Display.invert)
END Draw;
PROCEDURE DrawSwarm;
VAR i: INTEGER;
BEGIN
i := 0;
WHILE i < NrWasps DO
Age(Wasps[i]); AccelerateWasp(Wasps[i]); Move(Wasps[i]); ReflectWasp(Wasps[i]); Draw(Wasps[i]); INC(i)
END;
i := random() MOD NrBees; Bees[i].vx := Bees[i].vx + Rand(3); (* change a random bee *)
i := random() MOD NrBees; Bees[i].vy := Bees[i].vy + Rand(3);
i := 0;
WHILE i < NrBees DO
Age(Bees[i]); AccelerateBee(Bees[i]); Move(Bees[i]); Draw(Bees[i]); INC(i)
END
END DrawSwarm;
PROCEDURE GetPar(VAR S: Texts.Scanner; lbound, ubound, default: INTEGER; VAR val: INTEGER; VAR list: BOOLEAN);
BEGIN
IF list THEN
IF S.class = Texts.Int THEN
IF S.i < lbound THEN val := lbound ELSIF S.i < ubound THEN val := SHORT(S.i) ELSE val := ubound END
ELSE
list := FALSE; val := default
END;
Texts.Scan(S)
ELSE
val := default
END
END GetPar;
PROCEDURE Start*;
VAR msg: Viewers.ViewerMsg; S: Texts.Scanner; T: Texts.Text; pos, t, dummy: LONGINT; list: BOOLEAN;
BEGIN
Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
IF (S.class = Texts.Char) & (S.c = "^") THEN
Oberon.GetSelection(T, pos, dummy, t);
IF t >= 0 THEN Texts.OpenScanner(S, T, pos); Texts.Scan(S) END
END;
list := TRUE; GetPar(S, 1, MaxWasps, 2, NrWasps, list); GetPar(S, 1, MaxBees, 100, NrBees, list); GetPar(S, 2, 20, 5, WaspAcc, list);
GetPar(S, 1, 19, 3, BeeAcc, list); GetPar(S, 0, 20, 5, Delay, list);
InitSwarm;
msg.id := Viewers.suspend; Viewers.Broadcast(msg);
Display.ReplConst(Display.black, 0, 0, Display.Width, Display.Height, Display.replace);
WHILE Input.Available() = 0 DO
DrawSwarm; Wait(Delay); firstTime := FALSE
END;
msg.id := Viewers.restore; Viewers.Broadcast(msg)
END Start;
END Swarm.Start 5 200 5 3 20
(* Parameters: number of wasps, number of bees, wasp acceleration, bee acceleration, delay between steps (Input.Tick's) *)
Swarm.Start
System.State Swarm